import utils from 'src/utils'
import { createId, idToRgba } from 'src/utils/helper'
import { Listener, Shape, Props } from '../types/shape'
import { shapeType, shapeType_ } from 'src/types/drawBoard'


// 基类
export default class implements Shape {
  private id: string

  private listeners: { [name: string]: Listener[] }

  public type: shapeType_

  public selectable: boolean = true

  public props = new Props()

  public actived: boolean = false

  public transformOrigin: 'top_left' | 'center' = 'center'

  constructor(type?: shapeType_) {
    this.type = type || shapeType.other
    this.id = createId()
    this.props.name = this.id
    // 设置id为只读
    Object.defineProperty(this.props, 'id', {
      value: this.id,
      enumerable: false,
      configurable: false,
      writable: false
    })
    this.listeners = {}
  }
  on(eventName: string, listener: Listener) {
    if (this.listeners[eventName]) {
      this.listeners[eventName].push(listener)
    } else {
      this.listeners[eventName] = [listener]
    }
  }
  draw(ctx: CanvasRenderingContext2D, osCtx: OffscreenCanvasRenderingContext2D) {
    throw new Error('Method not implemented.')
  }
  // 矩形变换
  transform(ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D) {
    if (this.transformOrigin == 'top_left') return
    const { x, y, width, height, rotation, lateX, lateY, scaleX, scaleY } = this.props
    ctx.translate(lateX, lateY)

    ctx.translate(x, y)
    ctx.rotate(Math.PI / 180 * rotation)
    ctx.scale(scaleX, scaleY)
    ctx.translate(-x, -y)
    ctx.translate(-width / 2, -height / 2)
  }
  /**
   * 
   * @param ctx 画布上下文
   * @param type 画布类型 1-画布实例，2-画布镜像
   */
  initOptions(ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, type: 1 | 2) {
    const { bgcolor, borderColor, textColor, borderWidth, shadowColor, shadowBlur, size, textBaseline, opacity, textAlign } = this.props
    switch (type) {
      case 1:
        ctx.fillStyle = textColor
        ctx.fillStyle = bgcolor
        ctx.strokeStyle = borderColor
        ctx.lineWidth = borderWidth
        ctx.shadowColor = shadowColor;
        ctx.shadowBlur = shadowBlur;
        ctx.font = `${size}px Arial`
        ctx.textBaseline = textBaseline
        ctx.textAlign = textAlign
        ctx.globalAlpha = opacity
        break
      case 2:
        const [r, g, b, a] = idToRgba(this.getRgbaId())

        ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`
        ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`
        ctx.lineWidth = borderWidth
        break
    }
  }
  // 画镜像
  drawMirror(osCtx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D) {
    const { x, y, width, height } = this.props

    osCtx.save()

    this.transform(osCtx)

    osCtx.beginPath()
    this.initOptions(osCtx, 2)
    osCtx.rect(x, y, width, height)
    osCtx.fill()
    osCtx.stroke()
    osCtx.closePath()

    osCtx.restore()
  }
  getListeners() {
    return this.listeners
  }
  getRgbaId(): string {
    return this.id
  }
  setProps(option: Props) {
    utils.object.Assign(option, this.props)
  }
  get Listeners() {
    return this.listeners;
  }
  get Id() {
    return this.id
  }
}
